﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
using Medianamik.Core;
using Medianamik.Core.Lock;
using Medianamik.UI.Lock;

namespace Medianamik.UI.Controls
{
    public class CheckLockButton : SecuredImageButton, IScriptControl
    {
        private static readonly string _lockedArg = "Locked";
        private static readonly string _notLockedArg = "NotLocked";

        protected override void AddAttributesToRender(HtmlTextWriter writer)
        {
            if (Enabled && MedianamikContext.Current.LockingIsEnabled
                && !DesignMode)
            {
                var onclick = string.Format(@"$find('{0}').checkLock('{1}',function(){{ {2} ;}}, function(){{ {3} ;}}); return false; "
                    , ClientID
                    , NodeId
                    , OnClientLocked
                    , OnClientNotLocked);

                writer.AddAttribute(HtmlTextWriterAttribute.Onclick, onclick);
            }
            base.AddAttributesToRender(writer);
        }

        protected override void OnPreRender(EventArgs e)
        {
            if (Enabled && MedianamikContext.Current.LockingIsEnabled
                && !this.DesignMode)
            {
                // Test for ScriptManager and register if it exists
                var sm = ScriptManager.GetCurrent(Page);
                if (sm == null)
                {
                    throw new Exception("A ScriptManager control must exist on the current page.");
                }
                sm.RegisterScriptControl(this);
            }

            ScriptManager.GetCurrent(Page).Services.Add(new ServiceReference("/Medianamik/Services/LockWebService.asmx"));
            base.OnPreRender(e);
        }

        protected override void Render(HtmlTextWriter writer)
        {
            if (Enabled
                && !this.DesignMode)
            {
                var sm = ScriptManager.GetCurrent(Page);
                sm.RegisterScriptDescriptors(this);
                base.Render(writer);
            }
            else
            {
                //Tout simplement afficher une image
                writer.Write("<img src=\"{0}\" alt=\"{1}\" class=\"{2}\" />",
                    LockedOrDisabledImageUrl, AlternateText, CssClass);
            }
        }

        public string OnClientLocked
        {
            get
            {
                return ViewState["OnClientLocked"] as string ??
                    OnClientLockedDefault;
            }
            set
            {
                ViewState["OnClientLocked"] = value;
            }
        }

        public string OnClientNotLocked
        {
            get
            {
                if (NavigateUrl.Length > 0)
                    return String.Concat("location.href='", NavigateUrl,
                        "'");

                return ViewState["OnClientNotLocked"] as string ??
                    OnClientNotLockedDefault;
            }
            set
            {
                ViewState["OnClientNotLocked"] = value;
            }
        }

        private string OnClientLockedDefault
        {
            get
            {
                return Page.ClientScript.GetPostBackEventReference(this, _lockedArg);
            }
        }

        private string OnClientNotLockedDefault
        {
            get
            {
                return Page.ClientScript.GetPostBackEventReference(this, _notLockedArg);
            }
        }

        protected override void RaisePostBackEvent(string eventArgument)
        {
            if (eventArgument != null && eventArgument.Equals(_lockedArg))
                OnLocked(new CommandEventArgs("OnLocked", NodeId.ToString()));
            else
                OnNotLocked(new CommandEventArgs("OnNotLocked", NodeId.ToString()));
        }

        private static readonly object _locked = new object();
        public event CommandEventHandler Locked
        {
            add
            {
                Events.AddHandler(_locked, value);
            }
            remove
            {
                Events.RemoveHandler(_locked, value);
            }
        }
        protected void OnLocked(CommandEventArgs e)
        {
            var handler = Events[_locked] as CommandEventHandler;

            if (Enabled && handler != null)
            {
                handler(this, e);
            }
        }

        private static readonly object _notLocked = new object();
        public event CommandEventHandler NotLocked
        {
            add
            {
                Events.AddHandler(_notLocked, value);
            }
            remove
            {
                Events.RemoveHandler(_notLocked, value);
            }
        }


        protected void OnNotLocked(CommandEventArgs e)
        {
            var handler = Events[_notLocked] as CommandEventHandler;

            if (Enabled && handler != null)
            {
                handler(this, e);
            }
        }

        public virtual string LockedOrDisabledImageUrl
        {
            get
            {
                return ViewState["LockedOrDisabledImageUrl"] as string ?? string.Empty;
            }
            set
            {
                ViewState["LockedOrDisabledImageUrl"] = value;
            }
        }

        public virtual string NavigateUrl
        {
            get
            {
                return ViewState["NavigateUrl"] as string ?? string.Empty;
            }
            set
            {
                ViewState["NavigateUrl"] = value;
            }
        }

        public override string ImageUrl
        {
            get
            {
                return Enabled && !IsLocked ? base.ImageUrl : LockedOrDisabledImageUrl;
            }
            set
            {
                base.ImageUrl = value;
            }
        }

        private bool? _isLocked;
        protected bool IsLocked
        {
            get
            {
                if (!_isLocked.HasValue)
                    _isLocked = LockManager.IsLocked(NodeId);

                return _isLocked.GetValueOrDefault();
            }
        }

        public IEnumerable<ScriptDescriptor> GetScriptDescriptors()
        {
            ScriptControlDescriptor descriptor = new ScriptControlDescriptor("Medianamik.LockRequester", ClientID);
            return new ScriptDescriptor[] { descriptor };
        }

        public IEnumerable<ScriptReference> GetScriptReferences()
        {
            ScriptReference reference = new ScriptReference();
            reference.Path = Medianamik.Core.Sugar.Resources.GetWebResourceUrl("Lock.lockRequester.js", Page, GetType(), Assembly.GetAssembly(GetType()));
            return new ScriptReference[] { reference };
        }
    }
}
